from flask_socketio import SocketIO
import logging
from datetime import datetime
import json

sync_logger = logging.getLogger('sync')

class JSONEncoder(json.JSONEncoder):
    """自定义JSON编码器，处理datetime对象"""
    def default(self, obj):
        if isinstance(obj, datetime):
            return obj.strftime('%Y-%m-%d %H:%M:%S')
        return super().default(obj)

def serialize_dict(d):
    """序列化字典中的所有datetime对象"""
    result = {}
    for key, value in d.items():
        if isinstance(value, dict):
            result[key] = serialize_dict(value)
        elif isinstance(value, datetime):
            result[key] = value.strftime('%Y-%m-%d %H:%M:%S')
        else:
            result[key] = value
    return result

class WebSocketManager:
    _instance = None
    
    def __new__(cls):
        if cls._instance is None:
            cls._instance = super(WebSocketManager, cls).__new__(cls)
            cls._instance._initialized = False
        return cls._instance
    
    def __init__(self):
        if self._initialized:
            return
            
        self.socketio = None
        self._initialized = True
    
    def init_app(self, app):
        """初始化WebSocket"""
        self.socketio = SocketIO(
            app,
            cors_allowed_origins="*",
            async_mode='threading',
            logger=True,
            engineio_logger=True,
            ping_timeout=5,
            ping_interval=25,
            always_connect=True,
            json=json
        )
        
        @self.socketio.on('connect')
        def handle_connect():
            sync_logger.info("WebSocket客户端连接成功")
            
        @self.socketio.on('disconnect')
        def handle_disconnect():
            sync_logger.info("WebSocket客户端断开连接")
            
        sync_logger.info("WebSocket管理器初始化成功")
    
    def emit_sync_status(self, sync_dir_id, status, message):
        """发送同步状态更新"""
        try:
            if self.socketio:
                data = {
                    'sync_dir_id': sync_dir_id,
                    'status': status,
                    'message': message
                }
                data = serialize_dict(data)
                sync_logger.debug(f"准备发送WebSocket同步状态: {data}")
                self.socketio.emit('sync_status', data)
                sync_logger.debug(f"WebSocket发送同步状态成功: dir_id={sync_dir_id}, status={status}, message={message}")
        except Exception as e:
            sync_logger.error(f"发送WebSocket消息失败: {str(e)}")
    
    def emit_sync_history(self, sync_dir_id, history_item):
        """发送同步历史更新"""
        try:
            if self.socketio:
                # 将history_item从sqlite3.Row转换为dict并序列化datetime
                history_dict = dict(history_item)
                data = {
                    'sync_dir_id': sync_dir_id,
                    'history_item': serialize_dict(history_dict)
                }
                sync_logger.debug(f"准备发送WebSocket同步历史: {data}")
                self.socketio.emit('sync_history', data)
                sync_logger.debug(f"WebSocket发送同步历史成功: dir_id={sync_dir_id}")
        except Exception as e:
            sync_logger.error(f"发送WebSocket消息失败: {str(e)}")

websocket_manager = WebSocketManager() 